defer
defer後邊會接一個函數,但該函數不會立刻被執行,而是等到包含它的程式返回時(包含它的函數執行了return語句、運行到函數結尾自動返回、對應的goroutine panic)defer函數才會被執行。通常用於資源釋放、列印日誌、異常捕獲等
func main() {
f, err := os.Open(filename)
if err != nil {
return err
}
/**
* defer要寫在err判斷的後面而不是os.Open後面
* 如果資源沒有獲取成功,就沒有必要對資源執行釋放操作
* 如果err不為nil而執行資源執行釋放操作,有可能導致panic
*/
defer f.Close()
}
panic內置函數停止當前goroutine的正常執行,當函數F調用panic時,函數F的正常執行被立即停止,然後運行所有在F函數中的defer函數,然後F返回到調用他的函數對於調用者G,F函數的行為就像panic一樣,終止G的執行並運行G中所defer函數,此過程會一直繼續執行到goroutine所有的函數。panic可以通過內置的recover來捕獲。
recover內置函數用來管理含有panic行為的goroutine,recover運行在defer函數中,獲取panic拋出的錯誤值,並將程式恢復成正常執行的狀態。如果在defer函數之外調用recover,那麼recover不會停止並且捕獲panic錯誤如果goroutine中沒有panic或者捕獲的panic的值為nil,recover的返回值也是nil。由此可見,recover的返回值表示當前goroutine是否有panic行為